package cn.edu.tju.elm.service;

import cn.edu.tju.elm.model.CreditHistory;
import cn.edu.tju.elm.model.CreditRating;
import cn.edu.tju.elm.model.CreditEventType;
import cn.edu.tju.elm.model.VirtualWallet;
import cn.edu.tju.elm.repository.CreditHistoryRepository;
import cn.edu.tju.elm.repository.VirtualWalletRepository;
import cn.edu.tju.elm.service.CreditService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

@Service
@Transactional
public class CreditServiceImpl implements CreditService {

    @Autowired
    private VirtualWalletRepository walletRepository;

    @Autowired
    private CreditHistoryRepository creditHistoryRepository;

    @Override
    @Transactional
    public void setVipStatus(Long userId, boolean isVip, LocalDateTime expireTime) {
        VirtualWallet wallet = getWalletByUserId(userId);
        wallet.setVipStatus(isVip, expireTime);
        walletRepository.save(wallet);

        // 记录信用历史
        CreditHistory history = new CreditHistory();
        history.setWalletId(wallet.getId());
        history.setEventType(isVip ? CreditEventType.VIP_ACTIVATION : CreditEventType.VIP_EXPIRATION);
        history.setDescription(isVip ? "用户激活VIP状态" : "用户VIP状态到期");
        history.setOldCreditRating(wallet.getCreditRating().name());
        history.setNewCreditRating(wallet.getCreditRating().name());
        creditHistoryRepository.save(history);
    }

    @Override
    public boolean isVipUser(Long userId) {
        VirtualWallet wallet = getWalletByUserId(userId);
        return wallet.isVip();
    }

    @Override
    public CreditRating getCreditRating(Long userId) {
        VirtualWallet wallet = getWalletByUserId(userId);
        return wallet.getCreditRating();
    }

    @Override
    public BigDecimal getUsedCredit(Long userId) {
        VirtualWallet wallet = getWalletByUserId(userId);
        return wallet.getUsedCredit();
    }

    @Override
    public BigDecimal getRemainingCredit(Long userId) {
        VirtualWallet wallet = getWalletByUserId(userId);
        return wallet.getRemainingCredit();
    }

    @Override
    public boolean isOverdue(Long userId) {
        VirtualWallet wallet = getWalletByUserId(userId);
        return wallet.isOverdue();
    }

    @Override
    public BigDecimal calculateOverdueInterest(Long userId) {
        VirtualWallet wallet = getWalletByUserId(userId);
        return wallet.calculateOverdueInterest();
    }

    @Override
    public List<CreditHistory> getCreditHistory(Long userId) {
        VirtualWallet wallet = getWalletByUserId(userId);
        return creditHistoryRepository.findByWalletIdOrderByCreateTimeDesc(wallet.getId());
    }

    @Override
    @Transactional
    public void processOverdueCheck() {
        // 获取所有有信用欠款的VIP用户钱包
        List<VirtualWallet> wallets = walletRepository.findAll().stream()
                .filter(wallet -> wallet.isVip() && 
                        (wallet.getUsedCredit().compareTo(BigDecimal.ZERO) > 0 || 
                         wallet.getOverdueAmount().compareTo(BigDecimal.ZERO) > 0))
                .toList();

        for (VirtualWallet wallet : wallets) {
            // 检查是否逾期
            if (wallet.getOverdueStartTime() != null) {
                long overdueDays = java.time.Duration.between(wallet.getOverdueStartTime(), LocalDateTime.now()).toDays();
                
                // 如果超过最大允许逾期天数，降低信用评级
                if (overdueDays > wallet.getCreditRating().getMaxAllowedOverdueDays()) {
                    // 记录信用评级变更
                    CreditHistory history = new CreditHistory();
                    history.setWalletId(wallet.getId());
                    history.setEventType(CreditEventType.CREDIT_RATING_CHANGE);
                    history.setOldCreditRating(wallet.getCreditRating().name());
                    wallet.setCreditRating(CreditRating.DEFAULT);
                    history.setNewCreditRating(wallet.getCreditRating().name());
                    history.setDescription("因长期逾期，信用评级降为违约");
                    creditHistoryRepository.save(history);
                    
                    walletRepository.save(wallet);
                }
            }
        }
    }

    private VirtualWallet getWalletByUserId(Long userId) {
        return walletRepository.findByUserId(userId)
                .orElseThrow(() -> new IllegalArgumentException("钱包不存在"));
    }
}